using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Threading;
using System.IO.Ports;

namespace VCPTest_NET
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void comboBox1_GotFocus(object sender, EventArgs e)
        {
            string[] AvailableCOMPorts;

            // Clear combobox
            this.comboBox1.Items.Clear();
            this.comboBox1.Text = "";

            // Determine the COM ports currently available
            AvailableCOMPorts = System.IO.Ports.SerialPort.GetPortNames();

            for (int j = 0; j < AvailableCOMPorts.Length; j++)
            {
                // Add it to the combo box.
                this.comboBox1.Items.Add(AvailableCOMPorts[j]);
            }

        }

        private void OpenBtn_Click(object sender, EventArgs e)
        {
            if (this.comboBox1.Text.CompareTo(System.String.Empty) != 0)
            {

                // Set port name to that selected in the combobox
                serialPort1.PortName = this.comboBox1.Text;
                
                // Set port parameters
                serialPort1.BaudRate = Convert.ToInt32(cbBaudRate.Text);
                serialPort1.DataBits = Convert.ToInt32(cbDataBits.Text);
                serialPort1.StopBits = System.IO.Ports.StopBits.One;
                switch (cbStopBits.Text)
                {
                    case "1":
                        serialPort1.StopBits = System.IO.Ports.StopBits.One;
                        break;

                    case "2":
                        serialPort1.StopBits = System.IO.Ports.StopBits.Two;
                        break;

                    default:
                        serialPort1.StopBits = System.IO.Ports.StopBits.One;
                        break;
                }

                switch (cbParity.Text)
                {
                    case "None":
                        serialPort1.Parity = System.IO.Ports.Parity.None;
                        break;

                    case "Odd":
                        serialPort1.Parity = System.IO.Ports.Parity.Odd;
                        break;

                    case "Even":
                        serialPort1.Parity = System.IO.Ports.Parity.Even;
                        break;

                    case "Mark":
                        serialPort1.Parity = System.IO.Ports.Parity.Mark;
                        break;

                    case "Space":
                        serialPort1.Parity = System.IO.Ports.Parity.Space;
                        break;

                    default:
                        serialPort1.Parity = System.IO.Ports.Parity.None;
                        break;
                }

                switch (cbParity.Text)
                {
                    case "None":
                        serialPort1.Handshake = System.IO.Ports.Handshake.None;
                        break;

                    case "RTS-CTS":
                        serialPort1.Handshake = System.IO.Ports.Handshake.RequestToSend;
                        break;

                    case "Xon-Xoff":
                        serialPort1.Handshake = System.IO.Ports.Handshake.XOnXOff;
                        break;

                    default:
                        serialPort1.Handshake = System.IO.Ports.Handshake.None;
                        break;
                }


                // Try to open the serial port
                try
                {
                    serialPort1.Open();
                }
                catch (System.Exception)
                {
                    MessageBox.Show("Failed to open selected port.\nIs it open in another application?\n(" + ")");
                }
                finally
                {
                    // If we have successfully opened the port, enable/disable buttons
                    if (serialPort1.IsOpen)
                    {
                        serialPort1.RtsEnable = true;
                        serialPort1.DtrEnable = true;

                        // Set write timeout
                        serialPort1.WriteTimeout = 5000;

                        // Disable Open button
                        OpenBtn.Enabled = false;
                        // Disable combo box
                        comboBox1.Enabled = false;

                        // Enable Close button
                        CloseBtn.Enabled = true;
                        // Enable Send button
                        SendBtn.Enabled = true;
                        // Enable Send button
                        ClearBtn.Enabled = true;
                        // Enable Write button
                        btnWrite.Enabled = true;

                        // Disable properties page controls
                        cbBaudRate.Enabled = false;
                        cbDataBits.Enabled = false;
                        cbStopBits.Enabled = false;
                        cbParity.Enabled = false;
                        cbFlowControl.Enabled = false;
                        tbXonChar.Enabled = false;
                        tbXoffChar.Enabled = false;

                    }
                }
            }
        }

        private void CloseBtn_Click(object sender, EventArgs e)
        {
            try
            {
                // Close the serial port
                serialPort1.Close();
            }
            catch (System.Exception)
            {
                MessageBox.Show("Failed to close port.");
            }

            // Enable Open button
            OpenBtn.Enabled = true;
            // Enable combo box
            comboBox1.Enabled = true;

            // Disable Close button
            CloseBtn.Enabled = false;
            // Disable Send button
            SendBtn.Enabled = false;
            // Disable Clear button
            ClearBtn.Enabled = false;
            // Disable Write button
            btnWrite.Enabled = false;

            // Enable properties page controls
            cbBaudRate.Enabled = true;
            cbDataBits.Enabled = true;
            cbStopBits.Enabled = true;
            cbParity.Enabled = true;
            cbFlowControl.Enabled = true;
            if (cbFlowControl.Text == "Xon-Xoff")
            {
                // Enable our Xon and Xoff text boxes
                tbXonChar.Enabled = true;
                tbXoffChar.Enabled = true;
            }
            else
            {
                // Disable our Xon and Xoff text boxes
                tbXonChar.Enabled = false;
                tbXoffChar.Enabled = false;
            }
        }

        private void ClearBtn_Click(object sender, EventArgs e)
        {
            textBox2.Text = "";
        }

        private void SendBtn_Click(object sender, EventArgs e)
        {
            // Clear text box
            this.textBox1.Text = "";
        }




        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            // This event handler fires each time data is received by the serial port.
            // Read available data from the serial port and display it on the form.
            // This event does not run in the UI thread, so need to 
            // use delegate function
            
            string strErg = serialPort1.ReadExisting();
            this.BeginInvoke(new EventHandler(delegate
            {
                SetTheText(strErg);

            }));
            Application.DoEvents();
        }


        private void SetTheText(string strText)
        {
            textBox2.Text += strText;
        }


        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            // If the port is closed, don't try to send a character.
            if (!serialPort1.IsOpen) return;

            // If the port is Open, declare a char[] array with one element.
            char[] buff = new char[1];

            // Load element 0 with the key character.
            buff[0] = e.KeyChar;

            try
            {
                // Send the one character buffer.
                serialPort1.Write(buff, 0, 1);
            }
            catch (System.Exception)
            {
                MessageBox.Show("Failed to write to port.");
            }
            // Set the KeyPress event as handled so the character won't
            // display locally. If you want it to display, omit the next line.
            e.Handled = true;

            // Also add the character to the textbox
            textBox1.Text += buff[0].ToString();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.DataReceived += new
                 SerialDataReceivedEventHandler(serialPort1_DataReceived);

            // Initialise port parameters on Properties tab
            cbBaudRate.Text = "9600";
            cbDataBits.Text = "8";
            cbStopBits.Text = "1";
            cbParity.Text = "None";
            cbFlowControl.Text = "None";
                       
        }

        private void btnQuit_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                try
                {
                    serialPort1.Close();
                }
                catch (System.Exception)
                {
                    MessageBox.Show("Failed to close selected port.");
                }
            }
            serialPort1.DataReceived -= new
                             SerialDataReceivedEventHandler(serialPort1_DataReceived);

            Application.Exit();
        }

        private void cbFlowControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbFlowControl.Text == "Xon-Xoff")
            {
                // Enable our Xon and Xoff text boxes
                tbXonChar.Enabled = true;
                tbXoffChar.Enabled = true;
            }
            else
            {
                // Disable our Xon and Xoff text boxes
                tbXonChar.Enabled = false;
                tbXoffChar.Enabled = false;
            }
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            // If the port is closed, don't try to send data.
            if (!serialPort1.IsOpen) return;

            // If the port is Open, declare a char[] array with 256 elements.
            char[] buff = new char[256];

            // Load element with the corresponding character.
            for (byte i = 0; i < 255; i++) {
                buff[i] = Convert.ToChar(i);
            }
            try
            {
                // Send the character buffer.
                serialPort1.Write(buff, 0, 256);
            }
            catch (System.Exception)
            {
                MessageBox.Show("Failed to write to port.");
            }
        }

    }
}


